package com.aiyige.page.my.download;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.Guideline;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.db.DBHelper;
import com.aiyige.base.db.dao.DownloadFileDao;
import com.aiyige.base.db.dao.DownloadModelDao;
import com.aiyige.base.db.table.DownloadFile;
import com.aiyige.base.db.table.DownloadModel;
import com.aiyige.page.my.download.adapter.DownloadModelAdapter;
import com.aiyige.page.my.download.event.EventAddLocalVideo;
import com.aiyige.page.my.download.event.EventRefreshDownloadProgress;
import com.aiyige.page.my.download.event.EventToggleEdit;
import com.aiyige.page.my.download.util.DownloadUtil;
import com.aiyige.page.player.PlayerInfo;
import com.aiyige.page.publish.normalvideo.model.PublishNormalVideoItem;
import com.aiyige.page.publish.util.PublishUtil;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.FileUtil;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.SafeAsyncTask;
import com.aiyige.utils.StringUtils;
import com.aiyige.utils.ToastX;
import com.aiyige.utils.UUIDUtil;
import com.aiyige.utils.VideoUtil;
import com.alibaba.android.arouter.launcher.ARouter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.j256.ormlite.misc.TransactionManager;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

public class DownloadDataPage extends Fragment {
    public static final int FILTER_TYPE_ALL = 1;
    public static final int FILTER_TYPE_LEARN_VIDEO = 2;
    public static final int FILTER_TYPE_NORMAL_VIDEO = 3;
    public static final int FILTER_TYPE_LOCAL_VIDEO = 4;

    @BindView(R.id.mainRv)
    RecyclerView mainRv;
    Unbinder unbinder;
    DownloadModelAdapter downloadModelAdapter;
    int filterType = FILTER_TYPE_ALL;
    @BindView(R.id.selectAllIv)
    ImageView selectAllIv;
    @BindView(R.id.selectAllBtn)
    TextView selectAllBtn;
    @BindView(R.id.deleteBtn)
    TextView deleteBtn;
    @BindView(R.id.guideline)
    Guideline guideline;
    @BindView(R.id.editLayout)
    ConstraintLayout editLayout;
    boolean edit = false;
    EventBus eventBus;
    @BindView(R.id.addLocalVideoBtn)
    ImageView addLocalVideoBtn;

    public DownloadDataPage() {
        eventBus = EventBus.builder().build();
    }


    public static DownloadDataPage newInstance(int filterTYpe) {
        DownloadDataPage page = new DownloadDataPage();
        page.setFilterType(filterTYpe);
        return page;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.page_download_data, container, false);
        unbinder = ButterKnife.bind(this, view);
        if (filterType == FILTER_TYPE_LOCAL_VIDEO) {
            addLocalVideoBtn.setVisibility(View.VISIBLE);
        } else {
            addLocalVideoBtn.setVisibility(View.INVISIBLE);
        }
        downloadModelAdapter = new DownloadModelAdapter(getActivity());
        mainRv.setLayoutManager(new LinearLayoutManager(getContext()));
        downloadModelAdapter.bindToRecyclerView(mainRv);
        downloadModelAdapter.setEmptyView(R.layout.standard_empty_layout);
        downloadModelAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                DownloadModel downloadModel = downloadModelAdapter.getItem(position);
                if (!downloadModel.isEdit()) {
                    switch (downloadModel.getModelType()) {
                        case DownloadUtil.MODEL_TYPE_LEARN_VIDEO:
                            ARouter.getInstance()
                                    .build(ARouterConfig.DownloadDetailPage)
                                    .withString("title", downloadModel.getTitle())
                                    .withInt("parentType", downloadModel.getModelType())
                                    .withString("parentId", downloadModel.getId())
                                    .navigation();
                            break;
                        case DownloadUtil.MODEL_TYPE_NORMAL_VIDEO:
                            if (downloadModel.getProgressStatus() != DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED) {
                                ARouter.getInstance()
                                        .build(ARouterConfig.DownloadDetailPage)
                                        .withString("title", downloadModel.getTitle())
                                        .withInt("parentType", downloadModel.getModelType())
                                        .withString("parentId", downloadModel.getId())
                                        .navigation();
                            } else {
                                try {
                                    List<DownloadFile> downloadFileList = DownloadFileDao.getDao()
                                            .queryBuilder()
                                            .where()
                                            .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                                            .and()
                                            .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                            .and()
                                            .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                            .and()
                                            .eq(DownloadFile.PROGRESS_STATUS_FIELD, DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED)
                                            .query();
                                    if (ListUtil.isEmpty(downloadFileList)) {
                                        throw new Exception(StringUtils.getString(R.string.not_found_video));
                                    }
                                    DownloadFile downloadFile = downloadFileList.get(0);
                                    List<PlayerInfo> playList = new ArrayList<>();
                                    playList.add(PlayerInfo.newBuilder()
                                            .cover(TextUtils.isEmpty(downloadFile.getCoverLocalUrl()) ? downloadFile.getCoverRemoteUrl() : downloadFile.getCoverLocalUrl())
                                            .isFree(true)
                                            .path(downloadFile.getFileLocalUrl())
                                            .title(downloadFile.getTitle())
                                            .build());
                                    ARouter.getInstance()
                                            .build(ARouterConfig.PlayerPage)
                                            .withSerializable("playList", (Serializable) playList)
                                            .withString("modelId", downloadModel.getId())
                                            .withInt("fileId", downloadFile.getId())
                                            .navigation();
                                } catch (Exception e) {
                                    ToastX.show(e);
                                }
                            }
                            break;
                        case DownloadUtil.MODEL_TYPE_LOCAL_VIDEO:
                            try {
                                List<DownloadFile> downloadFileList = DownloadFileDao.getDao()
                                        .queryBuilder()
                                        .where()
                                        .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                                        .and()
                                        .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                        .and()
                                        .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                        .and()
                                        .eq(DownloadFile.PROGRESS_STATUS_FIELD, DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED)
                                        .query();
                                if (ListUtil.isEmpty(downloadFileList)) {
                                    throw new Exception(StringUtils.getString(R.string.not_found_video));
                                }
                                DownloadFile downloadFile = downloadFileList.get(0);
                                List<PlayerInfo> playList = new ArrayList<>();
                                playList.add(PlayerInfo.newBuilder()
                                        .cover(TextUtils.isEmpty(downloadFile.getCoverLocalUrl()) ? downloadFile.getCoverRemoteUrl() : downloadFile.getCoverLocalUrl())
                                        .isFree(true)
                                        .path(downloadFile.getFileLocalUrl())
                                        .title(downloadFile.getTitle())
                                        .build());
                                ARouter.getInstance()
                                        .build(ARouterConfig.PlayerPage)
                                        .withSerializable("playList", (Serializable) playList)
                                        .withString("modelId", downloadModel.getId())
                                        .withInt("fileId", downloadFile.getId())
                                        .navigation();
                            } catch (Exception e) {
                                ToastX.show(e);
                            }
                            break;
                    }
                } else {
                    downloadModel.setSelected(!downloadModel.isSelected());
                    downloadModelAdapter.setData(position, downloadModel);
                    updateSelectAllIv();
                }
            }
        });
        return view;
    }

    public EventBus getEventBus() {
        return eventBus;
    }

    public void registerEventBus() {
        try {
            if (!eventBus.isRegistered(this)) {
                eventBus.register(this);
            }
        } catch (Exception e) {

        }
    }

    public void unregisterEventBus() {
        try {
            if (eventBus.isRegistered(this)) {
                eventBus.unregister(this);
            }
        } catch (Exception e) {
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        registerEventBus();
        query();
        DownloadUtil.startDownload();
    }

    public boolean checkAllSelected() {
        if (ListUtil.isEmpty(downloadModelAdapter.getData())) return false;
        boolean result = true;
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            if (!downloadModel.isSelected()) {
                result = false;
                break;
            }
        }
        return result;
    }


    public void updateSelectAllIv() {
        if (checkAllSelected()) {
            selectAllIv.setImageResource(R.drawable.order_screen_selected);
        } else {
            selectAllIv.setImageResource(R.drawable.order_screen_normal);
        }
    }

    public void query() {
        new QueryTask(getActivity()).execute();
    }

    public int getFilterType() {
        return filterType;
    }

    public void setFilterType(int filterType) {
        this.filterType = filterType;
    }

    @OnClick({R.id.selectAllBtn, R.id.deleteBtn, R.id.addLocalVideoBtn})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.selectAllBtn: {
                if (!checkAllSelected()) {
                    doSelectAll();
                } else {
                    unSelectAll();
                }
                updateSelectAllIv();
                break;
            }
            case R.id.deleteBtn: {
                doBatchDelete();
                updateSelectAllIv();
                break;
            }
            case R.id.addLocalVideoBtn: {
                PictureSelector.create(getActivity())
                        .openGallery(PictureMimeType.ofVideo())
                        .isCamera(false)
                        .previewImage(false)
                        .previewVideo(false)
                        .maxSelectNum(Integer.MAX_VALUE)
                        .selectionMedia(getExistVideo())
                        .minSelectNum(1)
                        .selectionMode(PictureConfig.MULTIPLE)
                        .forResult(MyDownloadPage.REQUEST_CODE_ADD_LOCAL_VIDEO);
            }
        }
    }

    public List<LocalMedia> getExistVideo() {
        List<LocalMedia> localMediaList = new LinkedList<>();
        List<DownloadModel> downloadModelList = downloadModelAdapter.getData();
        List<DownloadFile> downloadFileList = new LinkedList<>();
        for (DownloadModel downloadModel : downloadModelList) {
            downloadFileList.clear();
            try {
                QueryBuilder<DownloadFile, Integer> queryBuilder = DownloadFileDao.getDao().queryBuilder();
                downloadFileList.addAll(queryBuilder.where()
                        .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                        .and()
                        .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                        .and()
                        .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                        .query());
            } catch (Exception e) {
            }
            for (DownloadFile downloadFile : downloadFileList) {
                LocalMedia localMedia = new LocalMedia();
                localMedia.setPictureType("video/mp4");
                localMedia.setMimeType(PictureConfig.TYPE_VIDEO);
                localMedia.setPath(downloadFile.getFileLocalUrl());
                localMediaList.add(localMedia);
            }
        }
        return localMediaList;
    }


    public void doBatchDelete() {
        Iterator<DownloadModel> iterator = downloadModelAdapter.getData().iterator();
        while (iterator.hasNext()) {
            final DownloadModel downloadModel = iterator.next();
            if (!downloadModel.isSelected()) continue;
            try {
                TransactionManager.callInTransaction(DBHelper.getInstance().getConnectionSource(), new Callable<Object>() {
                    @Override
                    public Object call() throws Exception {
                        UpdateBuilder<DownloadModel, String> downloadModelUpdateBuilder = DownloadModelDao.getDao().updateBuilder();
                        downloadModelUpdateBuilder.updateColumnValue(DownloadModel.CONTROL_OPTION_FIELD, filterType != FILTER_TYPE_LOCAL_VIDEO ? DownloadUtil.CONTROL_OPTION_DELETE : DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY);
                        downloadModelUpdateBuilder.where().eq(DownloadModel.ID_FIELD, downloadModel.getId());
                        downloadModelUpdateBuilder.update();

                        UpdateBuilder<DownloadFile, Integer> downloadFileUpdateBuilder = DownloadFileDao.getDao().updateBuilder();
                        downloadFileUpdateBuilder.updateColumnValue(DownloadFile.CONTROL_OPTION_FIELD, filterType != FILTER_TYPE_LOCAL_VIDEO ? DownloadUtil.CONTROL_OPTION_DELETE : DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY);
                        downloadFileUpdateBuilder.where().eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId());
                        downloadFileUpdateBuilder.update();
                        return null;
                    }
                });

            } catch (Exception e) {

            }
            iterator.remove();
        }
        downloadModelAdapter.notifyDataSetChanged();
    }


    public void updateEditLayout() {
        if (edit) {
            editLayout.setVisibility(View.VISIBLE);
        } else {
            editLayout.setVisibility(View.GONE);
        }
    }

    public void updateEditState() {
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setEdit(edit);
            downloadModel.setSelected(false);
        }
        downloadModelAdapter.notifyDataSetChanged();
    }

    public void doSelectAll() {
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setSelected(true);
        }
        downloadModelAdapter.notifyDataSetChanged();
    }

    public void unSelectAll() {
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setSelected(false);
        }
        downloadModelAdapter.notifyDataSetChanged();
    }

    public class QueryTask extends SafeAsyncTask<Object, Object, Object> {
        List<DownloadModel> downloadModelList = new LinkedList<>();

        public QueryTask(Activity activity) {
            super(activity, R.string.loading);
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {
                ToastX.show((Exception) o);
            } else {
                downloadModelAdapter.setNewData(downloadModelList);
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            DownloadUtil.scanDownload();
            try {
                switch (filterType) {
                    case FILTER_TYPE_LOCAL_VIDEO:
                        downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                .where()
                                .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                .and()
                                .eq(DownloadModel.MODEL_TYPE_FIELD, DownloadUtil.MODEL_TYPE_LOCAL_VIDEO)
                                .query());
                        break;
                    case FILTER_TYPE_LEARN_VIDEO:
                        downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                .where()
                                .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                .and()
                                .eq(DownloadModel.MODEL_TYPE_FIELD, DownloadUtil.MODEL_TYPE_LEARN_VIDEO)
                                .query());
                        break;
                    case FILTER_TYPE_NORMAL_VIDEO:
                        downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                .where()
                                .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                .and()
                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                .and()
                                .eq(DownloadModel.MODEL_TYPE_FIELD, DownloadUtil.MODEL_TYPE_NORMAL_VIDEO)
                                .query());
                        break;
                }
                return null;

            } catch (Exception e) {
                return e;
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onEvent(EventToggleEdit event) {
        edit = event.isEnableEdit();
        updateEditState();
        updateEditLayout();
        updateSelectAllIv();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(EventRefreshDownloadProgress event) {
        downloadModelAdapter.getEventBus().post(event);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(EventAddLocalVideo event) {
        List<LocalMedia> localMediaList = event.getLocalMediaList();
        mergeSelect(localMediaList);
    }

    public void mergeSelect(List<LocalMedia> localMediaList) {
        new MergeSelectedTask(getActivity(), localMediaList).execute();
    }

    @Override
    public void onDestroyView() {
        unregisterEventBus();
        super.onDestroyView();
        unbinder.unbind();
    }

    public class MergeSelectedTask extends SafeAsyncTask<Object, Object, Object> {
        List<LocalMedia> localMediaList;
        List<DownloadModel> newDownloadModelList;

        public MergeSelectedTask(Activity activity, List<LocalMedia> localMediaList) {
            super(activity, R.string.text_process);
            this.localMediaList = localMediaList;
            newDownloadModelList = new LinkedList<>();
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {
                ToastX.show((Exception) o);
            } else {
                downloadModelAdapter.addData(newDownloadModelList);
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                List<DownloadFile> existFileList = new LinkedList<>();
                for (DownloadModel model : downloadModelAdapter.getData()) {
                    try {
                        List<DownloadFile> tempList = DownloadFileDao.getDao().queryBuilder()
                                .where().eq(DownloadFile.PARENT_ID_FIELD, model.getId())
                                .and()
                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                .and()
                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                .query();
                        existFileList.addAll(tempList);
                    } catch (Exception e) {

                    }
                }
                Iterator<LocalMedia> iterator = localMediaList.iterator();
                outLoop:
                while (iterator.hasNext()) {
                    LocalMedia localMedia = iterator.next();
                    for (DownloadFile downloadFile : existFileList) {
                        if (downloadFile.getFileLocalUrl().equals(localMedia.getPath())) {
                            iterator.remove();
                            continue outLoop;
                        }
                    }
                }
                for (LocalMedia localMedia : localMediaList) {
                    try {
                        String coverLocalUrl = VideoUtil.getVideoCover(localMedia.getPath(), 0);
                        DownloadModel downloadModel = DownloadModel.newBuilder()
                                .downloadDate(System.currentTimeMillis())
                                .modelType(DownloadUtil.MODEL_TYPE_LOCAL_VIDEO)
                                .controlOption(DownloadUtil.CONTROL_OPTION_DOWNLOAD)
                                .coverLocalUrl(coverLocalUrl)
                                .edit(edit)
                                .id(UUIDUtil.generate())
                                .mediaNum(1)
                                .userId(AccountUtil.getCurrentUser().getId())
                                .progressStatus(DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED)
                                .title(FileUtil.getFileName(localMedia.getPath()))
                                .releaseDate(System.currentTimeMillis())
                                .build();
                        DownloadFile downloadFile = DownloadFile.newBuilder()
                                .fileLocalUrl(localMedia.getPath())
                                .fileType(DownloadUtil.DOWNLOAD_FILE_TYPE_VIDEO)
                                .controlOption(DownloadUtil.CONTROL_OPTION_DOWNLOAD)
                                .duration(localMedia.getDuration())
                                .parentId(downloadModel.getId())
                                .progressStatus(DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED)
                                .userId(AccountUtil.getCurrentUser().getId())
                                .totalSize(FileUtil.getFileSize(localMedia.getPath()))
                                .downloadedSize(FileUtil.getFileSize(localMedia.getPath()))
                                .coverLocalUrl(coverLocalUrl)
                                .title(FileUtil.getFileName(localMedia.getPath()))
                                .build();
                        DownloadModelDao.getDao().create(downloadModel);
                        DownloadFileDao.getDao().create(downloadFile);
                        newDownloadModelList.add(downloadModel);
                    } catch (Exception e) {

                    }

                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }
    }

}

